/*
 * Copyright (c) 2017, www.zm0618.com All Rights Reserved..
 */

package com.light.hessian.remoting.client.balance;

import com.light.hessian.provider.config.ProviderStatus;
import com.light.hessian.provider.slot.ProviderStatusSlot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ClassUtils;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by zhaojun on 2017/02/12.
 */
public class RoundrobinBalancer extends  BaseBalancer{


    protected static  final Logger logger= LoggerFactory.getLogger(RoundrobinBalancer.class);


    private final AtomicInteger n =new AtomicInteger(-1);//访问次数计数位

    public RoundrobinBalancer() {
    }

    public RoundrobinBalancer(List<ProviderStatusSlot> statusSlots) {
        super(statusSlots);
    }

    static {
        Thread.currentThread().setContextClassLoader(ClassUtils.getDefaultClassLoader());
    }
    @Override
    public String getBalancerName() {
        return Balance.roundrobin.name();
    }

    @Override
    public ProviderStatusSlot select() {
        ProviderStatusSlot[] cStatusSlots = this.statusSlots;
        int count = n.incrementAndGet();
        if (count < 0) {//计数器溢出
            synchronized (this) {
                int index0 = n.get();
                if (index0 < 0) {
                    n.getAndSet(-1);
                    count = 0;
                } else {
                    count = index0;
                }
            }
        }

        int len = cStatusSlots.length;
        int index=(int) (count % len);

        ProviderStatusSlot statusSlot = cStatusSlots[index];

        if (statusSlot.isShowBalancer()){
            logger.info("=====>{}",statusSlot);
        }
        if (statusSlot.getStatus()== ProviderStatus.UP){
            return statusSlot;
        }else{//如果服务节点下线 从新选择节点
            return this.failback(index,cStatusSlots);
        }
    }

    /*private long nextCount() {

        long index = n.getAndIncrement();
        System.out.println("nextCount-->"+index);
        if (index < 0) {//计数器溢出
            synchronized (this) {
                long index0 = n.getAndIncrement();
                if (index0 < 0) {
                    n.getAndSet(0);
                    index = 0;
                } else {
                    index = index0;
                }
            }
        }
        return index;
    }*/
}
